package com.example.rabbitmq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 自动配置
 * 1、RabbitConfiguration
 * 2、有自动配置了连接工厂ConnectionFactory
 * 3、RabbitProperties:封装了RabbitMQ的配置
 * 4、RabbitTemplate：给RabbitMQ发送消息
 * 5、AmqpAdmin：RabbitMQ系统管理功能组件
 *      AmqpAdmin：创建和删除 Queue、Exchange、Binding
 * @EnableRabbit+@RabbitListener监听消息内容
 */
@Component
@Configuration
//实现BeanPostProcessor类，使用Bean的生命周期函数
public class DirectRabbitConfig implements BeanPostProcessor {
    //这是创建交换机和队列用的rabbitAdmin对象
    @Resource
    private RabbitAdmin rabbitAdmin;

    //初始化rabbitAdmin
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
        RabbitAdmin rabbitAdmin=new RabbitAdmin(connectionFactory);
        //只有设置为true，spring才能加载RabbitAdmin这个类
        rabbitAdmin.setAutoStartup(true);
        return rabbitAdmin;
    }

    //实例化Bean后 也就是Bean的后置处理器


    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //创建交换机
        rabbitAdmin.declareExchange(rabbitmqDemoDirectExchange());
        //创建队列
        rabbitAdmin.declareQueue(rabbitmqDemoDirectQueue());
        return null;
    }

    @Bean
    public Queue rabbitmqDemoDirectQueue(){
        /**
         * 1、name:队列名称
         * 2、durable是否持久化
         * 3、exclusive：是否独享、排外的。如果设置为true，定义为排他队列，则只有创建者可以使用此队列
         * 4、autoDelete：是否自动删除 也就是临时队列 当最后一个消费者断开连接后 会自动删除
         */
        return new Queue(RabbitConfig.RABBITMQ_DEMO_NAME,true,false,false);
    }

    @Bean
    public DirectExchange rabbitmqDemoDirectExchange(){
        //Direct交换机
        return new DirectExchange(RabbitConfig.RABBIT_DEMO_DIRECT_EXCHANGE,true,false);
    }

    @Bean
    public Binding bindDirect(){
        //链式写法 绑定交换机和队列 并设置匹配键
        return BindingBuilder
                //绑定队列
                .bind(rabbitmqDemoDirectQueue())
                //到交换机
                .to(rabbitmqDemoDirectExchange())
                //并设置匹配键
                .with(RabbitConfig.RABBITMQ_DEMO_DIRECT_ROUTING);
    }
}
